package com.smartboot.plus.features.cluster;

import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

public class MqttClientIdGenerator {
    private static final String CLUSTER_PREFIX = "CLUSTER_";
    private static final AtomicInteger sequence = new AtomicInteger(0);
    private static final SecureRandom secureRandom = new SecureRandom();

    public enum GenerationStrategy {
        AUTO, UUID, TIMESTAMP_RANDOM, DEVICE_SEQUENTIAL, HYBRID
    }

    public static String generate() {
        return generate(GenerationStrategy.AUTO);
    }

    public static String generate(GenerationStrategy strategy) {
        switch (strategy) {
            case UUID: return uuidBased();
            case TIMESTAMP_RANDOM: return timestampRandomBased();
            case DEVICE_SEQUENTIAL: return deviceSequentialBased();
            case HYBRID: return hybridBased();
            default: return autoSelectStrategy();
        }
    }
    /**
     * UUID策略（
     */
    private static String uuidBased() {
        return "UUID_" + UUID.randomUUID().toString().replace("-", "");
    }
    /**
     * 时间戳+随机数策略
     */
    private static String timestampRandomBased() {
        long timestamp = System.currentTimeMillis() % 1000000000;
        int random = secureRandom.nextInt(10000);
        return String.format("TSR_%09d%04d", timestamp, random);
    }
    /**
     * 设备标识+序列号策略
     */
    private static String deviceSequentialBased() {
        int seq = sequence.incrementAndGet() % 10000;
        return String.format("%s_%04d", CLUSTER_PREFIX, seq);
    }
    /**
     * 混合策略（设备+时间+随机）
     */
    private static String hybridBased() {
        long timestamp = System.currentTimeMillis() % 1000000;
        int random = secureRandom.nextInt(1000);
        return String.format("%s_HYB_%06d%03d", CLUSTER_PREFIX, timestamp, random);
    }

    private static String autoSelectStrategy() {
        String containerId = System.getenv("HOSTNAME");
        if (containerId != null && !containerId.isEmpty()) {
            return "CTR_" + containerId;
        }
        return hybridBased();
    }

    public static boolean isValidClientId(String clientId) {
        if (clientId == null || clientId.isEmpty()) return false;
        if (clientId.length() > 256) return false;
        if (!clientId.matches("[a-zA-Z0-9_\\-]+")) return false;
        if (clientId.equalsIgnoreCase("server") || 
            clientId.equalsIgnoreCase("broker")) {
            return false;
        }
        return true;
    }

//    public static void main(String[] args) {
//        // 测试不同生成策略
//        System.out.println("UUID: " + generate(GenerationStrategy.UUID));
//        System.out.println("TimestampRandom: " + generate(GenerationStrategy.TIMESTAMP_RANDOM));
//        System.out.println("DeviceSequential: " + generate(GenerationStrategy.DEVICE_SEQUENTIAL));
//        System.out.println("Hybrid: " + generate(GenerationStrategy.HYBRID));
//        System.out.println("Auto: " + generate());
//        UUID: UUID_e87b56eb1e694fc4ba79ef98885c6d83
//TimestampRandom: TSR_9957242948798
//DeviceSequential: DEV_0001
//Hybrid: DEV_HYB_724302254
//Auto: DEV_HYB_724303555
//        // 验证有效性
//        String[] testIds = {
//            generate(),
//            "Valid_123",
//            "Invalid@id",
//            "",
//            generateLongId(260),   // 260字符的ID
//            generateLongId(256),   // 正好256字符的ID
//            "server"               // 保留关键字
//        };
//
//        for (String id : testIds) {
//            String displayId = id;
//            if (id.length() > 40) {
//                displayId = id.substring(0, 37) + "...";
//            }
//            System.out.printf("ID: %-40s Valid: %b%n", displayId, isValidClientId(id));
//        }
//    }

    // 生成长ID的替代方法（不使用String.repeat）
    private static String generateLongId(int length) {
        StringBuilder sb = new StringBuilder();
        String base = "long-id-";
        int baseLength = base.length();
        
        // 添加完整的基础字符串
        int fullCopies = length / baseLength;
        for (int i = 0; i < fullCopies; i++) {
            sb.append(base);
        }
        
        // 添加剩余字符
        int remaining = length % baseLength;
        if (remaining > 0) {
            sb.append(base.substring(0, remaining));
        }
        
        return sb.toString();
    }


}